package server.stackMachine;

import java.util.Stack;

public class IntegerStackMachine {

	public class StackOverflowException extends Exception {
		/**
		 * generated
		 */
		private static final long serialVersionUID = 3629675726788664708L;
	}
	public class NotEnoughElementsException extends Exception {
		/**
		 * generated
		 */
		private static final long serialVersionUID = 497884509096278276L;
	}

	final private Stack<Integer> stack = new Stack<Integer>();
	final private int maxSize;

	public IntegerStackMachine(int max) {
		this.maxSize = max;
	}

	public IntegerStackMachine() {
		this(128);
	}

	public void push(int i) throws StackOverflowException {
		if (this.stack.size() >= this.maxSize) throw new StackOverflowException();
		this.stack.push(i);
	}

	public void add() throws NotEnoughElementsException {
		if (this.stack.size() < 2) throw new NotEnoughElementsException();
		this.stack.push(this.stack.pop() + this.stack.pop());
	}

	
	public void sub() throws NotEnoughElementsException {
		if (this.stack.size() < 2) throw new NotEnoughElementsException();
		this.stack.push(-this.stack.pop() + this.stack.pop());
	}

	public void mul() throws NotEnoughElementsException {
		if (this.stack.size() < 2) throw new NotEnoughElementsException();
		this.stack.push(this.stack.pop() * this.stack.pop());
	}

	public void div() throws NotEnoughElementsException {
		if (this.stack.size() < 2) throw new NotEnoughElementsException();
		int i = this.stack.pop();
		this.stack.push(this.stack.pop() / i);
	}

	public void dup() throws NotEnoughElementsException, StackOverflowException {
		if (this.stack.size() < 2) throw new NotEnoughElementsException();
		if (this.stack.size() >= this.maxSize) throw new StackOverflowException();
		int i = this.stack.pop();
		this.stack.push(i);
		this.stack.push(i);
	}

	public int size() {
		return this.stack.size();
	}

	public int pop() throws NotEnoughElementsException {
		if (this.stack.size() < 1) throw new NotEnoughElementsException();
		return this.stack.pop();
	}

}
